package com.scorpio.goods.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.scorpio.basic.dto.NameIdDTO;
import com.scorpio.common.exception.CustomException;
import com.scorpio.common.utils.ConvertUtils;
import com.scorpio.goods.domain.GoodsEntity;
import com.scorpio.goods.domain.GoodsSkuEntity;
import com.scorpio.goods.domain.GoodsSkuSpecEntity;
import com.scorpio.goods.service.IGoodsService;
import com.scorpio.goods.service.IGoodsSkuService;
import com.scorpio.goods.service.IGoodsSkuSpecService;
import com.scorpio.goods.vo.AddGoodsSkuSpecVo;
import com.scorpio.goods.vo.AddGoodsSpecVo;
import com.scorpio.goods.vo.UpdateInventoryVo;
import com.scorpio.redis.cachelock.RedisLock;
import com.scorpio.redis.cachelock.RedisLockException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import com.scorpio.goods.mapper.GoodsSpecMapper;
import com.scorpio.goods.domain.GoodsSpecEntity;
import com.scorpio.goods.service.IGoodsSpecService;
import com.scorpio.common.service.impl.BaseServiceImpl;
import org.springframework.transaction.annotation.Transactional;

/**
 * 商品规格属性Service业务层处理
 *
 * @author scorpio
 * @date 2021-11-01
 */
@Service
public class GoodsSpecServiceImpl extends BaseServiceImpl<GoodsSpecMapper, GoodsSpecEntity> implements IGoodsSpecService {

    @Autowired
    private RedisLock redisLock;

    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private IGoodsSkuService goodsSkuService;

    @Autowired
    private IGoodsSkuSpecService skuSpecService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateInventory(UpdateInventoryVo vo) {
        String lockKey = "GoodsSpecServiceImpl_updateInventory:" + vo.getId();
        if (redisLock.lock(lockKey, 5)) {
            try {
                GoodsSpecEntity entity = baseDao.selectById(vo.getId());
                if (entity == null) {
                    throw new CustomException("商品比存在或已删除");
                } else if ((entity.getInventoryTotal() - vo.getInventoryTotal()) < 0) {
                    throw new CustomException("设置的库存减少已超出上限");
                }
                return baseDao.updateInventory(vo.getId(), vo.getInventoryTotal(), null);
            } finally {
                redisLock.unlock(lockKey);
            }
        }
        throw new RedisLockException();
    }

    //查询
    @Override
    public GoodsSpecEntity selectById(Long id) {
        GoodsSpecEntity entity = baseDao.selectById(id);
        setSpecName(entity);
        return entity;
    }

    private void setSpecName(GoodsSpecEntity entity) {
        if (entity == null) return;
        List<GoodsSkuSpecEntity> list = skuSpecService.selectSkuBySpec(entity.getId());
        StringBuilder sb = new StringBuilder();
        for (GoodsSkuSpecEntity skuEntity : list) {
            if (sb.length() > 0) {
                sb.append("、");
            }
            sb.append(skuEntity.getSpecName());
        }
        entity.setSpecsName(sb.toString());
    }

    //查询列表
    @Override
    public List<GoodsSpecEntity> selectList(GoodsSpecEntity entity) {
        List<GoodsSpecEntity> list = baseDao.list(entity);
        for (GoodsSpecEntity specEntity : list) {
            setSpecName(specEntity);
        }
        return list;
    }

    //新增$
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int save(AddGoodsSpecVo vo) {
        String lockKey = "GoodsSpecServiceImpl_" + vo.getGoodsId();
        if (redisLock.lock(lockKey, 5)) {
            try {
                GoodsEntity goodsEntity = goodsService.selectById(vo.getGoodsId());
                if (goodsEntity == null) {
                    throw new CustomException("指定商品不存在");
                }
                List<GoodsSkuEntity> slist = goodsSkuService.selectByGoods(vo.getGoodsId());
                for (GoodsSkuEntity item : slist) {
                    boolean isY = false;
                    for (AddGoodsSkuSpecVo specVo : vo.getSkuList()) {
                        if (specVo.getId().equals(item.getId())) {
                            isY = true;
                            break;
                        }
                    }
                    if (!isY) {
                        throw new CustomException("缺少sku参数");
                    }
                }
                GoodsSpecEntity entity = ConvertUtils.sourceToTarget(vo, GoodsSpecEntity.class);
                entity.setSoldoutTotal(100 + Math.round(500));
                int count = baseDao.insert(entity);
                if (count > 0) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(goodsEntity.getNumber());
                    List<GoodsSkuSpecEntity> skuList = new ArrayList<>();
                    for (AddGoodsSkuSpecVo specVo : vo.getSkuList()) {
                        GoodsSkuSpecEntity specEntity = new GoodsSkuSpecEntity();
                        specEntity.setGoodsId(vo.getGoodsId());
                        specEntity.setSkuId(specVo.getId());
                        specEntity.setSpecId(entity.getId());
                        specEntity.setSpecName(specVo.getSpecName());
                        skuList.add(specEntity);
                        if (skuSpecService.save(goodsEntity.getNumber(), specEntity) == 0) {
                            throw new CustomException("未知错误，请联系管理员");
                        }
                        sb.append(specEntity.getSpecNumber());
                    }
                    baseDao.updateSpecNumber(entity.getId(), sb.toString());
                    goodsService.updateSoldoutAndPrice(entity.getGoodsId());
                }
                return count;
            } finally {
                redisLock.unlock(lockKey);
            }
        }
        throw new RedisLockException();
    }

    @Override
    public int countByNumber(String number) {
        return baseDao.countByNumber(number);
    }

    //修改$
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int update(AddGoodsSpecVo vo) {
        GoodsEntity goodsEntity = goodsService.selectById(vo.getGoodsId());
        if (goodsEntity == null) {
            throw new CustomException("指定商品不存在");
        }
        int count = baseDao.adminUpdate(ConvertUtils.sourceToTarget(vo, GoodsSpecEntity.class));
        if (count > 0) {
            goodsService.updateSoldoutAndPrice(goodsEntity.getId());
        }
        return count;
    }

    //批量删除$
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteByIds(Long[] ids) {
        return baseDao.updateDelete(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateReturnInventory(Long id, Integer change) {
        if (change == null || change <= 0) {
            throw new CustomException("无效的参数");
        }
        String lockKey = "GoodsSpecServiceImpl_updateInventory:" + id;
        if (redisLock.lock(lockKey, 5)) {
            try {
                GoodsSpecEntity entity = baseDao.selectById(id);
                if (entity == null) {
                    throw new CustomException("商品不存在或已删除");
                }
                int count = goodsService.updateInventory(entity.getGoodsId(), -change);
                if (count == 0) {
                    throw new CustomException("操作失败");
                }
                return baseDao.updateInventory(id, change, change);
            } finally {
                redisLock.unlock(lockKey);
            }
        }
        throw new RedisLockException();
    }
}
